package control;

import java.util.List;
import java.util.ListIterator;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;

import core.Coordinate;
import factory.ComponentInterface;
import factory.components.Building;
import factory.components.Earth;
import factory.components.Gate;
import factory.components.QuaryCrane;
import factory.components.RailMountedGantry;
import factory.components.ReachStacker;
import factory.components.RoadTruck;
import factory.components.RubberTiredGantry;
import factory.components.Stack;
import factory.components.StraddleCarrier;
import factory.components.Terminal;
import factory.components.TerminalTruck;
import factory.components.Vessel;
import factory.components.Water;

public class ComponentPlacement {
	private List<ComponentInterface> componentList;
	private int[][] matr;
	private boolean vanMarTerminal = false;
	private Point matrixSize = new Point(500, 300);

	/**
	 * Beallitja a componentListet
	 * 
	 * @param componentList
	 *            a lista
	 */
	public ComponentPlacement(List<ComponentInterface> componentList) {
		this.componentList = componentList;
		matr = new int[matrixSize.x][matrixSize.y];
	}

	/**
	 * Leellenorzi, hogy a komponens rajta van-e olyan komponensen, amire rakhato
	 * 
	 * @param pri
	 *            a prioritas
	 * @param comp
	 *            a komponens
	 * @return true ha rajta van, false ha nincs
	 */
	private boolean isUnder(int pri, ComponentInterface comp) {
		int sizeX, sizeY;
		if ((comp.getOrientation() == SWT.UP) || (comp.getOrientation() == SWT.DOWN)) {
			sizeX = comp.getSize().getX();
			sizeY = comp.getSize().getY();
		} else {
			sizeX = comp.getSize().getY();
			sizeY = comp.getSize().getX();
		}
		int posX = comp.getPosition().getX();
		int posY = comp.getPosition().getY();
		for (int i = posY; i < (posY + sizeY); i++) {
			for (int j = posX; j < (posX + sizeX); j++) {
				if (matr[j][i] != pri)
					return false;
			}
		}
		return true;
	}

	/**
	 * Leellenorzi h a QueriCrane fele rejta van-e a terminalon
	 * 
	 * @param comp
	 *            a QueriCrane komponens
	 * @return true ha rajta van, kulomben false
	 */
	private boolean isUnderQC(ComponentInterface comp) {
		int sizeX, sizeY;
		if ((comp.getOrientation() == SWT.UP) || (comp.getOrientation() == SWT.DOWN)) {
			sizeX = comp.getSize().getX() / 2;
			sizeY = comp.getSize().getY();
		} else {
			sizeX = comp.getSize().getY() / 2;
			sizeY = comp.getSize().getX();
		}
		int posX = comp.getPosition().getX();
		int posY = comp.getPosition().getY();
		for (int i = posY; i < posY + sizeY; i++) {
			for (int j = posX; j < posX + sizeX; j++) {
				if (matr[j][i] != 2)
					return false;
			}
		}
		return true;
	}

	/**
	 * Leellenorzi h a komponens alatt olyan komponens van-e amire le lehet rakni
	 * 
	 * @param comp
	 *            a komponens
	 * @param pri
	 *            a prioritas
	 * @return true ha a komponens alatt olyan komponens van, false ha nem
	 */
	private boolean isEmpty(ComponentInterface comp, int pri) {
		int sizeX, sizeY;
		if ((comp.getOrientation() == SWT.UP) || (comp.getOrientation() == SWT.DOWN)) {
			sizeX = comp.getSize().getX();
			sizeY = comp.getSize().getY();
		} else {
			sizeX = comp.getSize().getY();
			sizeY = comp.getSize().getX();
		}
		int posX = comp.getPosition().getX();
		int posY = comp.getPosition().getY();
		for (int i = posY; i < posY + sizeY; i++) {
			for (int j = posX; j < posX + sizeX; j++) {
				if (matr[j][i] > pri) {
					return false;
				}
			}
		}
		return true;
	}

	/**
	 * Leellenorzi, hogy terminal van-e a komponens mellet
	 * 
	 * @param comp
	 *            a komponens
	 * @return true ha terminal van mellete, kulomben false
	 */
	private boolean nextToTerminal(ComponentInterface comp) {
		int posX = comp.getPosition().getX();
		int posY = comp.getPosition().getY();
		int posSizeX = posX + comp.getSize().getX();
		int posSizeY = posY + comp.getSize().getY();
		int u = 0, d = 0, l = 0, r = 0, j = 0;
		for (int i = 0; i < comp.getSize().getX(); i++) {
			if (matr[posX + i][posY - 1] == 2) {
				if ((u == 0) || (j == i - 1)) {
					u++;
					j = i;
				} else {
					u = 0;
				}
			}
		}
		j = 0;
		for (int i = 0; i < comp.getSize().getX(); i++) {
			if (matr[posX + i][posSizeY] == 2) {
				if ((d == 0) || (j == i - 1)) {
					d++;
					j = i;
				} else {
					d = 0;
				}
			}
		}
		j = 0;
		for (int i = 0; i < comp.getSize().getY(); i++) {
			if (matr[posSizeX][posY + i] == 2) {
				if ((l == 0) || (j == i - 1)) {
					l++;
					j = i;
				} else {
					l = 0;
				}
			}
		}
		j = 0;
		for (int i = 0; i < comp.getSize().getY(); i++) {
			if (matr[posX - 1][posY + i] == 2) {
				if ((r == 0) || (j == i - 1)) {
					r++;
					j = i;
				} else {
					r = 0;
				}
			}
		}
		if ((u > 5) || (d > 5) || (l > 5) || (r > 5)
				|| ((u > 0) && (d > 0) || (u > 0) && (l > 0) || (u > 0) && (r > 0))
				|| ((d > 0) && (l > 0) || (d > 0) && (r > 0)) || ((l > 0) && (r > 0)))
			return true;
		return false;
	}

	/**
	 * Leellenorzi, hogy 1-nel tobb terminal van-e
	 * 
	 * @return true ha tobb a terminal, kulonben false
	 */
	private boolean notfirstTerminal() {
		ListIterator<ComponentInterface> li = componentList.listIterator();
		ComponentInterface ci = null;
		while (li.hasNext()) {
			ci = li.next();
			if (ci instanceof Terminal) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Leellenorzi, hogy a komponens egy megadott meretnel nagyobb-e
	 * 
	 * @param comp
	 *            komponens
	 * @param a
	 *            egyik meret
	 * @param b
	 *            masik meret
	 * @return true ha jo a komponens merete, kulonben false
	 */
	private boolean isSize(ComponentInterface comp, int a, int b) {
		if (!(((comp.getSize().getX() >= a) && (comp.getSize().getY() >= b)) || ((comp.getSize().getX() >= b) && (comp
				.getSize().getY() >= a)))) {
			return false;
		}
		return true;
	}

	/**
	 * Leellenorzi a stack meretet
	 * 
	 * @param comp
	 *            a stack komponens
	 * @param b
	 *            a minimum hosszusaga
	 * @return true ha jo a meret, kulonben false
	 */
	private boolean isSizeStack(ComponentInterface comp, int b) {
		int sizeX = comp.getSize().getX();
		int sizeY = comp.getSize().getY();
		if ((sizeX > 15) && (sizeX < 29)) {
			if (sizeY > b) {
				return true;
			}
		}
		sizeX = comp.getSize().getY();
		sizeY = comp.getSize().getX();
		if ((sizeX > 15) && (sizeX < 29)) {
			if (sizeY > b) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Leellenorzi a kapu meretet, es hogy a terminal szelen van-e
	 * 
	 * @param comp
	 *            a kapu komponens
	 * @return true ha a kapu lerakhato, kulonben false
	 */
	private boolean isGate(ComponentInterface comp) {
		int posX = comp.getPosition().getX();
		int posY = comp.getPosition().getY();
		int sizeX = comp.getSize().getX();
		int sizeY = comp.getSize().getY();
		if ((comp.getOrientation() == SWT.LEFT) || (comp.getOrientation() == SWT.RIGHT)) {
			if (((matr[posX][posY - 1] == 1) || (matr[posX][posY + sizeY] == 1)) && (sizeY == 1)
					&& (sizeX > 5) && (sizeX < 13)) {
				return true;
			}
		} else if ((((matr[posX - 1][posY] == 1) || (matr[posX + sizeX][posY] == 1)) && (sizeX == 1)
				&& (sizeY > 5) && (sizeY < 13))) {
			return true;
		}
		return false;
	}

	/**
	 * Leellenorzi, hogy legyen merete
	 * 
	 * @param comp
	 *            komponenst kap
	 * @return true ha van rendes merete, kulonben false
	 */
	private boolean isSize(ComponentInterface comp) {
		if ((comp.getSize().getX() == 0) || (comp.getSize().getY() == 0)) {
			return false;
		}
		return true;
	}

	/**
	 * Leellenorzi, hogy a komponensbe beleesike a koordinata
	 * 
	 * @param co
	 *            koordinata
	 * @param compI
	 *            komponens
	 * @return true ha beleesik a koordinata a komponensbe, false ha nem
	 */
	private boolean inCoordToComp(Coordinate co, ComponentInterface compI) {
		int sizeX, sizeY;
		if ((compI.getOrientation() == SWT.UP) || (compI.getOrientation() == SWT.DOWN)) {
			sizeX = compI.getSize().getX();
			sizeY = compI.getSize().getY();
		} else {
			sizeX = compI.getSize().getY();
			sizeY = compI.getSize().getX();
		}
		if ((co.getX() >= compI.getPosition().getX()) && (co.getY() >= compI.getPosition().getY())
				&& (co.getX() <= (compI.getPosition().getX() + sizeX))
				&& (co.getY() <= (compI.getPosition().getY() + sizeY))) {
			return true;
		}
		return false;
	}

	/**
	 * Megkeresi a komponenst, amelyik a co koordinatan van
	 * 
	 * @param co
	 *            koordinata, ahol keressuk a komponenst
	 * @param prio
	 *            prioritasa a keresett komponensnek
	 * @return vissza teritti a komponenst, amelyik a co koordinatan talalhato
	 */
	private ComponentInterface findComp(Coordinate co, int prio) {
		ListIterator<ComponentInterface> li = componentList.listIterator();
		while (li.hasNext()) {
			ComponentInterface ci = li.next();
			if (ci.getPriority() == prio) {
				if (inCoordToComp(co, ci)) {
					return ci;
				}
			}
		}
		return null;
	}

	/**
	 * Visszateritti a kivalasztott komponenst
	 * 
	 * @param co
	 *            koordinatat kap
	 * @return visszateritti azt a komponenst, amelyik a co koordinatan
	 *         talalhato
	 */
	public ComponentInterface getCompByCoordinate(Coordinate co) {
		if (matr[co.getX()][co.getY()] > 1) {
			for (int i = 2; i < 5; i++) {
				if (matr[co.getX()][co.getY()] == i) {
					return findComp(co, i);
				}
			}
		}
		return null;
	}

	/**
	 * Beteszi a matrixba a komponens prioritasat
	 * 
	 * @param comp
	 *            komponens amit betesz a matrixba
	 */
	public void addCompToMatrix(ComponentInterface comp) {
		int sizeX, sizeY;
		if ((comp.getOrientation() == SWT.UP) || (comp.getOrientation() == SWT.DOWN)) {
			sizeX = comp.getSize().getX();
			sizeY = comp.getSize().getY();
		} else {
			sizeX = comp.getSize().getY();
			sizeY = comp.getSize().getX();
		}
		int posX = comp.getPosition().getX();
		int posY = comp.getPosition().getY();
		for (int i = posY; i < posY + sizeY; i++) {
			for (int j = posX; j < posX + sizeX; j++) {
				if (!((comp.getClass().getSimpleName().equals("QuaryCrane")) && matr[j][i] == 0)) {
					matr[j][i] = comp.getPriority();
				}
			}
		}
	}

	/**
	 * Feltolti a matrixot a listaba szereplo komponensekkel
	 * 
	 * @param list
	 *            lista amibe a komponensek vannak
	 */
	public void addListToMatrix(List<ComponentInterface> list) {
		ListIterator<ComponentInterface> li = list.listIterator();
		ComponentInterface ci = null;
		componentList = list;
		while (li.hasNext()) {
			ci = li.next();
			addCompToMatrix(ci);
		}
	}

	public boolean emptyTruck(ComponentInterface comp) {
		Point pos = new Point(comp.getPosition().getX(), comp.getPosition().getY());
		Point size;
		if ((comp.getOrientation() == SWT.UP) || (comp.getOrientation() == SWT.DOWN)) {
			size = new Point(comp.getSize().getX(), comp.getSize().getY());
		} else {
			size = new Point(comp.getSize().getY(), comp.getSize().getX());
		}
		ListIterator<ComponentInterface> li = componentList.listIterator();
		ComponentInterface ci = null;
		while (li.hasNext()) {
			ci = li.next();
			if (ci.getClass().getSimpleName().equals("TerminalTruck")) {
				Point cip = new Point(ci.getPosition().getX(), ci.getPosition().getY());
				Point cis;
				if ((ci.getOrientation() == SWT.UP) || (ci.getOrientation() == SWT.DOWN)) {
					cis = new Point(ci.getSize().getX(), ci.getSize().getY());
				} else {
					cis = new Point(ci.getSize().getY(), ci.getSize().getX());
				}
				if (((pos.x >= cip.x) && (pos.x <= (cip.x + cis.x)))
						&& ((pos.y >= cip.y) && (pos.y <= (cip.y + cis.y))))
					return false;
				if (((pos.x + size.x >= cip.x) && (pos.x + size.x <= cip.x + cis.x))
						&& ((pos.y >= cip.y) && (pos.y <= (cip.y + cis.y))))
					return false;
				if (((pos.x >= cip.x) && (pos.x <= (cip.x + cis.x)))
						&& ((pos.y + size.y >= cip.y) && (pos.y + size.y <= cip.y + cis.y)))
					return false;
				if (((pos.x + size.x >= cip.x) && (pos.x + size.x <= cip.x + cis.x))
						&& ((pos.y + size.y >= cip.y) && (pos.y + size.y <= cip.y + cis.y)))
					return false;
			}
		}

		return true;
	}

	/**
	 * Megnezi h egy TerminalTruck lerakhato-e egy stackra
	 * 
	 * @param comp
	 *            egy TerminalTruck komponens
	 * @return true ha lerakhato, kulonben false
	 */
	private boolean isPlaceableStack(ComponentInterface comp) {
		int posX = comp.getPosition().getX();
		int posY = comp.getPosition().getY();
		ListIterator<ComponentInterface> li = componentList.listIterator();
		ComponentInterface co = null;
		while (li.hasNext()) {
			co = li.next();
			if (co.getClass().getSimpleName().equals("Stack")) {
				if (inCoordToComp(new Coordinate(posX, posY), co)) {
					int coX = co.getPosition().getX();
					int coY = co.getPosition().getY();
					if (co.getSize().getX() > co.getSize().getY()) {
						if ((comp.getOrientation() == SWT.LEFT) || (comp.getOrientation() == SWT.RIGHT)) {
							if (posY == coY + 1) {
								return true;
							}
							if (posY == coY + co.getSize().getY() - 4) {
								return true;
							}
							if ((posY >= coY + 4) && (posY <= coY + co.getSize().getY() - 7)) {
								if ((posX == coX)
										|| (posX + comp.getSize().getY() == coX + co.getSize().getX())) {
									return true;
								}
							}
						}
					} else {
						if ((comp.getOrientation() == SWT.UP) || (comp.getOrientation() == SWT.DOWN)) {
							if (posX == coX + 1) {
								return true;
							}
							if (posX == coX + co.getSize().getX() - 4) {
								return true;
							}
							if ((posX >= coX + 4) && (posX <= coX + co.getSize().getX() - 7)) {
								if ((posY == coY)
										|| (posY + comp.getSize().getY() == coY + co.getSize().getY())) {
									return true;
								}
							}
						}
					}
				}
			}
		}
		return false;
	}

	/**
	 * Leellenorzi, hogy a torlendo komponensen van-e mas komponens
	 * 
	 * @param toDel
	 *            komponens amit torolni szeretnenk
	 * @return true ha nincs rajta komponens, false hogy ha van
	 */
	public boolean isDeletable(ComponentInterface toDel) {
		if (toDel instanceof QuaryCrane){
			return true;
		}
		int sizeX, sizeY;
		if ((toDel.getOrientation() == SWT.UP) || (toDel.getOrientation() == SWT.DOWN)) {
			sizeX = toDel.getSize().getX();
			sizeY = toDel.getSize().getY();
		} else {
			sizeX = toDel.getSize().getY();
			sizeY = toDel.getSize().getX();
		}
		int posX = toDel.getPosition().getX();
		int posY = toDel.getPosition().getY();
		for (int i = posY; i < posY + sizeY; i++) {
			for (int j = posX; j < posX + sizeX; j++) {
				if (matr[j][i] != toDel.getPriority()) {
					return false;
				}
			}
		}
		return true;
	}

	/**
	 * Visszateriti, h a Stacken hany RailMountedGantry van
	 * 
	 * @param comp
	 *            a Stack komponens
	 * @return egy szam, h hany daru van a Stacken
	 */
	private int countGantry(ComponentInterface comp) {
		int count = 0;
		int posX = comp.getPosition().getX();
		int posY = comp.getPosition().getY();
		ListIterator<ComponentInterface> li = componentList.listIterator();
		ComponentInterface ci = null;
		while (li.hasNext()) {
			ci = li.next();
			if (ci.getClass().getSimpleName().equals("RailMountedGantry"))
				if (inCoordToComp(new Coordinate(posX, posY), ci)) {
					count++;
				} else if (inCoordToComp(new Coordinate(posX + comp.getSize().getX(), posY
						+ comp.getSize().getY()), ci)) {
					count++;
				}
		}
		return count;
	}

	/**
	 * Megvizsgalja, hogy lerakhato-e a RailMountedGantry a Stackre, es a
	 * poziciojat, meretet is atallitja
	 * 
	 * @param comp
	 *            RailMountedGantry komponens
	 * @return true ha igen, false ha nem
	 */
	private boolean isPlaceableRMG(ComponentInterface comp) {
		int posX = comp.getPosition().getX();
		int posY = comp.getPosition().getY();
		ListIterator<ComponentInterface> li = componentList.listIterator();
		ComponentInterface ci = null;
		while (li.hasNext()) {
			ci = li.next();
			if (ci.getClass().getSimpleName().equals("Stack")) {
				if (inCoordToComp(new Coordinate(posX, posY), ci)) {
					int count = countGantry(ci);
					if (count < 2) {
						if (ci.getSize().getX() > ci.getSize().getY()) {
							if (count == 0) {
								comp.setPosition(new Coordinate(ci.getPosition().getX(), ci.getPosition()
										.getY()));
								comp.setSize(new Coordinate(15, ci.getSize().getY()));
								return true;
							} else {
								comp.setPosition(new Coordinate(ci.getPosition().getX() + ci.getSize().getX()
										- 15, ci.getPosition().getY()));
								comp.setSize(new Coordinate(15, ci.getSize().getY()));
								return true;
							}
						} else {
							if (count == 0) {
								comp.setPosition(new Coordinate(ci.getPosition().getX(), ci.getPosition()
										.getY()));
								comp.setSize(new Coordinate(ci.getSize().getX(), 15));
								return true;
							} else {
								comp.setPosition(new Coordinate(ci.getPosition().getX(), ci.getPosition()
										.getY() + ci.getSize().getY() - 15));
								comp.setSize(new Coordinate(ci.getSize().getX(), 15));
								return true;
							}
						}
					}
				}
			}
		}
		return false;
	}

	public boolean emptyGantry(Coordinate x, int ori, ComponentInterface comp) {
		ListIterator<ComponentInterface> li = componentList.listIterator();
		ComponentInterface ci = null;
		while (li.hasNext()) {
			ci = li.next();
			if (ci.getClass().getSimpleName().equals("RubberTiredGantry")) {
				if (inCoordToComp(new Coordinate(ci.getPosition().getX(), ci.getPosition().getY()), comp)) {
					if (ori == SWT.LEFT) {
						if ((ci.getPosition().getX() <= x.getX())
								&& (ci.getPosition().getX() + ci.getSize().getX() >= x.getX())) {
							return false;
						}
						if ((ci.getPosition().getX() <= x.getX() + x.getY())
								&& (ci.getPosition().getX() + ci.getSize().getX() >= x.getX() + x.getY()))
							return false;
					} else {
						if ((ci.getPosition().getY() <= x.getX())
								&& (ci.getPosition().getY() + ci.getSize().getY() >= x.getX())) {
							return false;
						}
						if ((ci.getPosition().getY() <= x.getX() + x.getY())
								&& (ci.getPosition().getY() + ci.getSize().getY() >= x.getX() + x.getY()))
							return false;
					}
				}
			}

		}
		return true;
	}

	/**
	 * Megvizsgalja, hogy lerakhato-e a RubberTiredGantry a Stackre, es a
	 * poziciojat, meretet is atalitja
	 * 
	 * @param comp
	 * 			a komponens
	 * @return   true ha igen, false ha nem
	 */
	private boolean isPlaceableRTG(ComponentInterface comp) {
		int posX = comp.getPosition().getX();
		int posY = comp.getPosition().getY();
		ListIterator<ComponentInterface> li = componentList.listIterator();
		ComponentInterface ci = null;
		while (li.hasNext()) {
			ci = li.next();
			if (ci.getClass().getSimpleName().equals("Stack")) {
				if (inCoordToComp(new Coordinate(posX, posY), ci)) {
					if (ci.getSize().getX() > ci.getSize().getY()) {
						if ((posX >= ci.getPosition().getX() + 15)
								&& (posX + 6 <= ci.getPosition().getX() + ci.getSize().getX() - 15)) {
							if (emptyGantry(new Coordinate(posX, 6), SWT.LEFT, ci)) {
								comp.setPosition(new Coordinate(comp.getPosition().getX(), ci.getPosition()
										.getY()));
								comp.setSize(new Coordinate(6, ci.getSize().getY()));
								return true;
							}
						}
					} else {
						if ((posY >= ci.getPosition().getY() + 15)
								&& (posY + 6 <= ci.getPosition().getY() + ci.getSize().getY() - 15)) {
							if (emptyGantry(new Coordinate(posY, 6), SWT.UP, ci)) {
								comp.setPosition(new Coordinate(ci.getPosition().getX(), posY));
								comp.setSize(new Coordinate(ci.getSize().getX(), 6));
								return true;
							}
						}
					}
				}
			}
		}
		return false;
	}

	/**
	 * Leellenorzi, hogy a komponens lerakhato-e
	 * 
	 * @param comp
	 *            komponens
	 * @return true ha lerakhato, kulonben false
	 */
	public boolean isPlaceable(ComponentInterface comp) {
		if (((comp.getPosition().getX() + comp.getSize().getX() > matrixSize.x) || (comp.getPosition().getY()
				+ comp.getSize().getY() > matrixSize.y))
				|| ((comp.getPosition().getX() < 0) || (comp.getPosition().getY() < 0))) {
			return false;
		}
		if (comp instanceof RoadTruck) {
			if (isUnder(1, comp)) {
				if (isEmpty(comp, 1)) {
					return true;
				}
			}
		}
		if (comp instanceof Terminal) {
			if (!vanMarTerminal) {
				if (notfirstTerminal()) {
					vanMarTerminal = true;
				}
			}
			if (!vanMarTerminal) {
				if (!(isSize(comp, 60, 150))) {
					return false;
				}
			}
			if ((comp.getSize().getX() > 0) && (comp.getSize().getY() > 0)) {
				if (isUnder(1, comp)) {
					if (isEmpty(comp, 1)) {
						if ((matr[comp.getPosition().getX() + comp.getSize().getX()][1] == 0)
								&& (!vanMarTerminal)) {
							return true;
						}
						if (nextToTerminal(comp)) {
							return true;
						}
					}
				}
			}
		}
		if (comp instanceof TerminalTruck) {
			if (emptyTruck(comp))
				if (isPlaceableStack(comp)) {
					return true;
				}
			if (isUnder(2, comp)) {
				if (isEmpty(comp, 2)) {
					return true;
				}
			}
		}
		if (comp instanceof Building) {
			if (isSize(comp)) {
				if (isUnder(2, comp)) {
					if (isEmpty(comp, 2)) {
						return true;
					}
				}
			}
		}
		if (comp instanceof Gate) {
			if (isUnder(2, comp)) {
				if (isEmpty(comp, 2)) {
					if (isGate(comp)) {
						return true;
					}
				}
			}
		}
		if (comp instanceof QuaryCrane) {
			if (isUnderQC(comp)) {
				if ((matr[comp.getPosition().getX() + comp.getSize().getX() / 2][comp.getPosition().getY()] == 0)
						&& ((matr[comp.getPosition().getX() + comp.getSize().getX() / 2 - 1][comp
								.getPosition().getY()]) == 2)) {
					return true;
				}
			}
		}
		if (comp instanceof Stack) {
			if (isSizeStack(comp, 66)) {
				if (isUnder(2, comp)) {
					if (isEmpty(comp, 2)) {
						return true;
					}
				}
			}
		}
		if (comp instanceof RailMountedGantry) {
			if (isPlaceableRMG(comp)) {
				return true;
			}
		}
		if (comp instanceof ReachStacker) {
			if (isUnder(2, comp)) {
				if (isEmpty(comp, 2)) {
					return true;
				}
			}
		}
		if (comp instanceof RubberTiredGantry) {
			if (isPlaceableRTG(comp)) {
				return true;
			}
		}

		if (comp instanceof StraddleCarrier) {
			if (isUnder(2, comp)) {
				if (isEmpty(comp, 2)) {
					return true;
				}
			}
		}
		if (comp instanceof Vessel) {
			if (isSize(comp)) {
				if (isUnder(0, comp)) {
					if (isEmpty(comp, 0)) {
						return true;
					}
				}
			}
		}
		if (comp instanceof Water
				|| comp instanceof Earth) {
			return true;
		}
		return false;
	}
}
